package info.niwota.ziplock;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;

/**
 * @author qiangli
 * 
 */
public class FolderContentProvider extends ContentProvider {
	public static final File ZIP_IMPORT = new File(SDCard.getRoot(), "import");

	public static final File ZIP_BASE = new File(SDCard.getRoot(), "base");
	
	public class ZipFilenameFilter implements FilenameFilter {
		boolean loggedIn = false;

		public boolean accept(File dir, String filename) {
			if (filename.endsWith(".zip")) {
				return true;
			}
			if (filename.endsWith(".zip.enc")) {
				return loggedIn;
			}
			return false;
		}
	}

	public static final Uri CONTENT_URI = Uri
			.parse("content://info.niwota.ziplock.folder");

	public static final String AUTHORITY = "info.niwota.ziplock.folder";

	private static final UriMatcher URI_MATCHER;

	public static class Columns {
		public static final String _ID = android.provider.LiveFolders._ID;
		public static final String NAME = android.provider.LiveFolders.NAME;
		public static final String DESCRIPTION = android.provider.LiveFolders.DESCRIPTION;
		public static final String ICON_PACKAGE = android.provider.LiveFolders.ICON_PACKAGE;
		public static final String ICON_RESOURCE = android.provider.LiveFolders.ICON_RESOURCE;
		public static final String INTENT = android.provider.LiveFolders.INTENT;
		public static final String ENCRYPTED = "encrypted";
	}

	public static class ColumnsIndex {
		public static final int _ID = 0;
		public static final int NAME = 1;
		public static final int DESCRIPTION = 2;
		public static final int ICON_PACKAGE = 3;
		public static final int ICON_RESOURCE = 4;
		public static final int INTENT = 5;
		public static final int ENCRYPTED = 6;
	}

	private static final String[] COL_NAMES = new String[] { Columns._ID,
			Columns.NAME, Columns.DESCRIPTION, Columns.ICON_PACKAGE,
			Columns.ICON_RESOURCE, Columns.INTENT, Columns.ENCRYPTED };

	private static final int FOLDER = 1;

	private static final String TAG = "FolderContentProvider";

	static {
		URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		URI_MATCHER.addURI(AUTHORITY, "", FOLDER);
		URI_MATCHER.addURI(AUTHORITY, "/", FOLDER);
		URI_MATCHER.addURI(AUTHORITY, "/*", FOLDER);
	}

	private ZipFilenameFilter zipFilter = new ZipFilenameFilter();

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		throw new UnsupportedOperationException();
	}

	@Override
	public String getType(Uri uri) {
		return "vnd.android.cursor.dir/ziplock.folder";
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean onCreate() {
		return true;
	}

	@Override
	public int bulkInsert(Uri uri, ContentValues[] values) {
		return 0;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		if (Debug.DEBUG) {
			Log.d(TAG, "query: "
					+ uri
					+ " projection: "
					+ (projection == null ? "" : Arrays.asList(projection))
					+ " selection: "
					+ selection
					+ " args: "
					+ (selectionArgs == null ? "" : Arrays
							.asList(selectionArgs)) + " sortOrder: "
					+ sortOrder);
		}

		// int type = URI_MATCHER.match(uri);
		// if (type == UriMatcher.NO_MATCH) {
		// return null;
		// }

		try {
			MatrixCursor c = new MyMatrixCursor(COL_NAMES);
			c.setNotificationUri(getContext().getContentResolver(), uri);
			return c;
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		throw new UnsupportedOperationException();
	}

	private class MyMatrixCursor extends MatrixCursor {
		public MyMatrixCursor(String[] columnNames) throws Exception {
			super(columnNames);

			load();

		}

		protected void load() throws Exception {
			rowCount = 0;
			Context ctx = getContext();
			zipFilter.loggedIn = Preferences.isLoggedIn(ctx);
			File[] files = ZIP_BASE.listFiles(zipFilter);
			if (files == null) {
				return;
			}
			Arrays.sort(files);
			//
			int size = files.length;
			data = new Object[size * columnCount];
			for (int i = 0; i < size; i++) {
				File fi = files[i];
				String id = i + "";
				String name = fi.getName();
				boolean encrypted = (name.endsWith(".enc"));
				int image = (encrypted ? R.drawable.certificate : 0);
				String desc = fi.getPath();
				String p = fi.getPath().substring(1);
				Uri uri = Uri.withAppendedPath(CONTENT_URI, p);
				if (Debug.DEBUG) {
					Log.d(TAG, "add uri: " + uri);
				}
				Object[] row = new Object[] { id, dislayName(name), desc,
						getContext().getPackageName(), image, uri, encrypted };
				//
				addRow(row);
			}
		}

		@Override
		public boolean requery() {
			if (Debug.DEBUG) {
				Log.d(TAG, "requerying...");
			}
			try {
				load();
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
			return super.requery();
		}
	}

	private String dislayName(String name) {
		int len = name.length();
		if (name.endsWith(".zip")) {
			return name.substring(0, len - 4);
		}
		if (name.endsWith(".zip.enc")) {
			return name.substring(0, len - 8);
		}
		// not reachable
		return name;
	}

}
